package top.xiaoazi.futureletterserver.module.user.service;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.xiaoazi.futureletterserver.common.AppVariable;
import top.xiaoazi.futureletterserver.module.user.entity.User;
import top.xiaoazi.futureletterserver.module.user.mapper.UserMapper;
import top.xiaoazi.futureletterserver.module.user.vo.UserRedisVO;
import top.xiaoazi.futureletterserver.utils.*;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private EmailUtils emailUtils;

    /**
     * 判断账号密码是否正确
     * @param user
     * @return
     */
    public User isOk(User user) {
        // 账号密码是否输入正确
        User userInfo =  userMapper.getByUsername(user);
        if (userInfo == null || userInfo.getUserId() == null) {
            return new User();
        }
        if (!PasswordUtils.check(user.getPassword(), userInfo.getPassword())) {
            return new User();
        }
        return userInfo;
    }

    public User getByUsername(User user) {
        return userMapper.getByUsername(user);
    }
    public User getByUsername(String username) {
        User user = new User();
        user.setUsername(username);
        return userMapper.getByUsername(user);
    }

    public int upPassword(User user) {
        return userMapper.upPassword(user);
    }

    public List<User> getAllUser(Integer pageSize, String username, int offset) {
        List<User> list = userMapper.getAllUser(pageSize, username, offset);
        for (User user : list) {
            user.setPassword(null);
        }
        return list;
    }

    public User getByUserId(Integer userId) {
        return userMapper.getByUserId(userId);
    }

    public HashMap<String, Object> login(User resultUser, HttpServletRequest request) {
        HashMap<String, Object> map = new HashMap<>();
        // 1. 密码正确判断Redis是否存在，如果存在删除缓存
        String token = request.getHeader("Authorization");
        if (token != null && redisUtils.hasKey(token)) {
            redisUtils.delete(token);
        }

        // 2. 使用 jwt 工具创建 token 令牌
        map.put(AppVariable.JWT_USER_ID, resultUser.getUserId());
        String newToken = jwtUtils.generateToken(map);

        // 3. 将 token 保存至 redis 中 - redis key: token，value: User
        UserRedisVO user = new UserRedisVO(resultUser); // 转换 存入 redis 的格式
        redisUtils.set(newToken, user, 7, TimeUnit.DAYS);

        // 4. 登录成功后将 user 和 token 都返回
        map.remove(AppVariable.JWT_USER_ID);
        map.put(AppVariable.USER, user);
        map.put(AppVariable.TOKEN_NAME, newToken);
        return map;
    }

    public void exit(HttpServletRequest request) {
        String token =  request.getHeader(AppVariable.HEADER_TOKEN);
        if (token == null) {
            return;
        }
        // 删除 redis 缓存即可
        redisUtils.delete(token);
    }

    public User isCsdnScript(String token) {
        UserRedisVO user = (UserRedisVO)redisUtils.get(token);
        return userMapper.getByUserId(user.getUserId());
    }

    public String getCsdnCookie(UserRedisVO user) {
        return userMapper.getCsdnCookie(user);
    }

    public int setCsdnCookie(String csdnCookie, Integer userId) {
        return userMapper.setCsdnCookie(csdnCookie, userId);
    }

    public Integer getCsdnCookieState(Integer userId) {
        return userMapper.getCsdnCookieState(userId);
    }

    public Integer getCurUsePersonCount() {
        return userMapper.getCurUsePersonCount();
    }

    public int systemReg(User user) {
        // 1. 密码加密
        String resultPassword = PasswordUtils.encrypt(user.getPassword());
        user.setPassword(resultPassword);
        user.setCreateTime(TimeUtils.getTimeString());
        return userMapper.systemReg(user);
    }

    public int setOtherCommentToMe(User user) {
        return userMapper.setOtherCommentToMe(user);
    }

    public int setReplyCommentToOther(User user) {
        return userMapper.setReplyCommentToOther(user);
    }

    public String getOtherCommentToMe(Integer userId) {
        return userMapper.getOtherCommentToMe(userId);
    }

    public String getReplyCommentToOther(Integer userId) {
        return userMapper.getReplyCommentToOther(userId);
    }


    public int setUserImg(User user) {
        return userMapper.setUserImg(user);
    }

    public int modifyUserinfo(User user) {
        return userMapper.modifyUserinfo(user);
    }

    public User isExistEmail(String email) {
        return userMapper.isExistEmail(email);
    }

    public void generateEmailCode(User user) {
        // 1. 生成验证码
        String emailCode = UUID.randomUUID().toString().substring(0, 4);
        // 2. 发送邮件
        emailUtils.sendHtmlEmail("验证码", emailUtils.getDefaultEmailTemplate("你的邮箱验证码为：" + emailCode + "，有效期为3分钟。"), user.getEmail());
        // 3. 存入 redis
        redisUtils.set(user.getEmail(), emailCode, 3, TimeUnit.MINUTES);
    }

    public void generateRestPwdEmailCode(User user) {
        // 1. 生成验证码
        String emailCode = UUID.randomUUID().toString().substring(0, 4);
        // 2. 发送邮件
        emailUtils.sendHtmlEmail("更改密码", emailUtils.getDefaultEmailTemplate("你的账号"+user.getUsername()+"正在更改密码, 邮箱验证码为：" + emailCode + "，有效期为3分钟, 如果不是本人操作, 请忽略。"), user.getEmail());
        // 3. 存入 redis，验证码 3 分钟过期
        redisUtils.set(RedisKeyUtils.getRestPasswordEmailKey(user.getEmail()), emailCode, 3, TimeUnit.MINUTES);
    }

    public int reg(User user) {
        // 1. 密码加密
        String resultPassword = PasswordUtils.encrypt(user.getPassword());
        user.setPassword(resultPassword);
        // 2. 创建账号
        return userMapper.reg(user);
    }

    public Integer getAllCount(String username) {
        return userMapper.getAllCount(username);
    }

    public int sysUpdate(User user) {
        return userMapper.sysUpdate(user);
    }

    public int modifyPassword(User user) {
        String resultPassword = PasswordUtils.encrypt(user.getPassword());
        user.setPassword(resultPassword);
        return userMapper.modifyPassword(user);
    }
}
